package gui;

import dragManager.DefaultDraggableManager;
import dragManager.DragPolicy;
import error.GUIError;
import houseHold.House;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.SystemColor;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;

import RoomPanel.IDGenerator;
import RoomPanel.PanelBuilder;
import RoomPanel.RoomPanel;
import constants.Constants;

public class HouseEditor extends JFrame {

	private static HouseEditor INSTANCE = new HouseEditor(); // @jve:decl-index=0:visual-constraint="726,428"
	public static Vector<RoomPanel> panels = new Vector<RoomPanel>(); // @jve:decl-index=0:
	private static final long serialVersionUID = 1L;

	public static HouseEditor getInstance() {
		return INSTANCE;
	}

	/**
	 * This method initializes jMenuItem
	 * 
	 * @return javax.swing.JMenuItem
	 * @throws InterruptedException
	 */

	public static void main(String args[]) throws InterruptedException {
		HouseEditor.getInstance().show();

	}

	JButton Add = null;
	private JPanel AddRoomDialog = null;
	JDialog AddRoomDialogMain = null; // @jve:decl-index=0:visual-constraint="583,29"
	private JButton Cancel = null;
	private JPanel MainPanel = null;
	private String rName;
	public JPanel RoomBuilder = null;
	private JPanel RoomBuilderFrame = null;
	private JLabel RoomError = null;
	private JTextField RoomHeight = null;
	private JLabel RoomHeightLabel = null;
	private JTextField RoomLength = null;
	private JLabel RoomLengthLabel = null;
	private JTextField RoomName = null;
	private JLabel RoomNameLabel = null;
	private JLabel RoomType = null;

	private JTextField RoomWidth = null;

	private JLabel RoomWidthLabel = null;

	private JComboBox Type = null;

	/**
	 * This is the default constructor
	 */
	private HouseEditor() {
		super();
		initialize();
	}

	private void clearRoomDialog() {
		Type.setSelectedIndex(-1);
		RoomName.setText("");
		RoomLength.setText("");
		RoomWidth.setText("");
		RoomHeight.setText("");
		RoomError.setForeground(Color.BLUE);
		RoomError.setText("Please input room data...");
	}

	/**
	 * This method initializes Add
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getAdd() {
		if (Add == null) {
			Add = new JButton();
			Add.setBounds(new Rectangle(20, 210, 80, 30));
			Add.setText("Add");
			Add.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if (!GUIError.addRoomError()) {
						RoomPanel next = PanelBuilder.newPanel((String) Type
								.getSelectedItem(), rName, RoomWidth.getText(),
								RoomHeight.getText(), RoomLength.getText(),
								IDGenerator.getNextRoomID());
						panels.add(next);
						House.getInstance().addRoom(next.getRoom());
						RoomBuilder.add(next);
						next.addPopUpMenu();
						RoomBuilder.repaint();
						AddRoomDialogMain.setVisible(false);
						clearRoomDialog();
						IDGenerator.incrementRoomID();
					}
				}
			});
		}
		return Add;
	}

	/**
	 * This method initializes AddRoomDialog
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getAddRoomDialog() {
		if (AddRoomDialog == null) {
			RoomLengthLabel = new JLabel();
			RoomLengthLabel.setBounds(new Rectangle(20, 150, 60, 25));
			RoomLengthLabel.setHorizontalAlignment(SwingConstants.CENTER);
			RoomLengthLabel.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomLengthLabel.setToolTipText("Room length in centimeters");
			RoomLengthLabel.setText("Height:");
			RoomHeightLabel = new JLabel();
			RoomHeightLabel.setBounds(new Rectangle(20, 120, 60, 25));
			RoomHeightLabel.setHorizontalAlignment(SwingConstants.CENTER);
			RoomHeightLabel.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomHeightLabel.setToolTipText("Room width  in cenitmeters");
			RoomHeightLabel.setText("Width:");
			RoomWidthLabel = new JLabel();
			RoomWidthLabel.setBounds(new Rectangle(20, 90, 60, 25));
			RoomWidthLabel.setHorizontalAlignment(SwingConstants.CENTER);
			RoomWidthLabel.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomWidthLabel.setToolTipText("Room heigth in cenitmeters");
			RoomWidthLabel.setText("Length:");
			RoomNameLabel = new JLabel();
			RoomNameLabel.setBounds(new Rectangle(20, 60, 60, 25));
			RoomNameLabel.setHorizontalAlignment(SwingConstants.CENTER);
			RoomNameLabel.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomNameLabel
					.setToolTipText("Generated automatically from RoomID & RoomType");
			RoomNameLabel.setText("Name:");
			RoomType = new JLabel();
			RoomType.setBounds(new Rectangle(20, 20, 50, 25));
			RoomType.setHorizontalAlignment(SwingConstants.CENTER);
			RoomType.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomType.setToolTipText("Room Type");
			RoomType.setText("Type:");
			RoomError = new JLabel();
			RoomError.setBounds(new Rectangle(20, 180, 200, 25));
			RoomError.setText("Error");
			AddRoomDialog = new JPanel();
			AddRoomDialog.setBackground(new Color(250, 250, 250));
			AddRoomDialog.setLayout(null);
			AddRoomDialog.add(getRoomName(), null);
			AddRoomDialog.add(getType(), null);
			AddRoomDialog.add(getRoomWidth(), null);
			AddRoomDialog.add(getRoomHeight(), null);
			AddRoomDialog.add(getRoomLength(), null);
			AddRoomDialog.add(getAdd(), null);
			AddRoomDialog.add(getCancel(), null);
			AddRoomDialog.add(RoomError, null);
			AddRoomDialog.add(RoomType, null);
			AddRoomDialog.add(RoomNameLabel, null);
			AddRoomDialog.add(RoomWidthLabel, null);
			AddRoomDialog.add(RoomHeightLabel, null);
			AddRoomDialog.add(RoomLengthLabel, null);
		}
		return AddRoomDialog;
	}

	/**
	 * This method initializes AddRoomDialogMain
	 * 
	 * @return javax.swing.JDialog
	 */
	private JDialog getAddRoomDialogMain() {
		if (AddRoomDialogMain == null) {
			AddRoomDialogMain = new JDialog(this);
			AddRoomDialogMain.setSize(new Dimension(250, 300));
			AddRoomDialogMain.setTitle("Add new Room");
			AddRoomDialogMain.setContentPane(getAddRoomDialog());
			AddRoomDialogMain
					.addWindowListener(new java.awt.event.WindowAdapter() {
						@Override
						public void windowClosing(java.awt.event.WindowEvent e) {
							clearRoomDialog();
						}
					});
		}
		return AddRoomDialogMain;
	}

	/**
	 * This method initializes Cancel
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getCancel() {
		if (Cancel == null) {
			Cancel = new JButton();
			Cancel.setBounds(new Rectangle(120, 210, 100, 30));
			Cancel.setText("Cancel");
			Cancel.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					AddRoomDialogMain.setVisible(false);
					clearRoomDialog();
				}
			});
		}
		return Cancel;
	}

	/**
	 * This method initializes MainPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getMainPanel() {
		if (MainPanel == null) {
			MainPanel = new JPanel();
			MainPanel.setLayout(new BorderLayout());
			MainPanel.add(getRoomBuilderFrame(), null);
			MainPanel.setBackground(Color.white);
			DefaultDraggableManager manager = new DefaultDraggableManager();
			manager.registerDraggableContainer(RoomBuilder); // note I wired
			// them up
			// first.
			manager.setDragPolicy(DragPolicy.OPEN);
		}
		return MainPanel;
	}

	public RoomPanel getPanel(int id) {
		for (int i = 0; i < panels.size(); i++)
			if (panels.get(i).getPanelID() == id)
				return panels.get(i);
		return null;
	}

	/**
	 * This method initializes RoomBuilder
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getRoomBuilder() {
		if (RoomBuilder == null) {
			RoomBuilder = new JPanel();
			RoomBuilder.setLayout(null);
			RoomBuilder.setBackground(Color.white);
			RoomBuilder.setBounds(new Rectangle(13, 13, 400, 400));
			RoomBuilder.setToolTipText("Right click to add a new room");
			AddRoomPopup arpm = new AddRoomPopup();
			MousePopupListener PopupListener = new MousePopupListener();
			PopupListener.setParent(RoomBuilder);
			PopupListener.setPopup(arpm.getRoomPopup());
			RoomBuilder.addMouseListener(PopupListener);

		}
		return RoomBuilder;
	}

	/**
	 * This method initializes RoomBuilderFrame
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getRoomBuilderFrame() {
		if (RoomBuilderFrame == null) {
			RoomBuilderFrame = new JPanel();
			RoomBuilderFrame.setLayout(null);
			RoomBuilderFrame.setBounds(new Rectangle(0, 0, 400, 400));
			RoomBuilderFrame.setBackground(Color.white);
			RoomBuilderFrame.setBorder(BorderFactory.createCompoundBorder(
					BorderFactory
							.createLineBorder(SystemColor.activeCaption, 5),
					BorderFactory.createCompoundBorder(BorderFactory
							.createBevelBorder(BevelBorder.RAISED),
							BorderFactory
									.createBevelBorder(BevelBorder.LOWERED))));
			RoomBuilderFrame.add(getRoomBuilder(), null);
		}
		return RoomBuilderFrame;
	}

	/**
	 * This method initializes RoomHeight
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getRoomHeight() {
		if (RoomHeight == null) {
			RoomHeight = new JTextField();
			RoomHeight.setBounds(new Rectangle(100, 150, 120, 25));
			RoomHeight.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomHeight.setHorizontalAlignment(SwingConstants.CENTER);
			RoomHeight.addKeyListener(new java.awt.event.KeyAdapter() {
				@Override
				public void keyReleased(java.awt.event.KeyEvent e) {
					validateInput();
				}
			});
		}
		return RoomHeight;
	}

	public String getRoomHeightString() {
		return RoomHeight.getText();
	}

	/**
	 * This method initializes RoomLength
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getRoomLength() {
		if (RoomLength == null) {
			RoomLength = new JTextField();
			RoomLength.setBounds(new Rectangle(100, 90, 120, 25));
			RoomLength.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomLength.setHorizontalAlignment(SwingConstants.CENTER);
			RoomLength.addKeyListener(new java.awt.event.KeyAdapter() {
				@Override
				public void keyReleased(java.awt.event.KeyEvent e) {
					validateInput();
				}
			});
		}
		return RoomLength;
	}

	public String getRoomLengthString() {
		return RoomLength.getText();
	}

	/**
	 * This method initializes RoomName
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getRoomName() {
		if (RoomName == null) {
			RoomName = new JTextField();
			RoomName.setBounds(new Rectangle(100, 60, 120, 25));
			RoomName.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomName.setEditable(false);
			RoomName.setBackground(Color.white);
			RoomName.setHorizontalAlignment(SwingConstants.CENTER);
		}
		return RoomName;
	}

	/**
	 * This method initializes RoomWidth
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getRoomWidth() {
		if (RoomWidth == null) {
			RoomWidth = new JTextField();
			RoomWidth.setBounds(new Rectangle(100, 120, 120, 25));
			RoomWidth.setFont(new Font("SansSerif", Font.BOLD, 12));
			RoomWidth.setHorizontalAlignment(SwingConstants.CENTER);
			RoomWidth.addKeyListener(new java.awt.event.KeyAdapter() {
				@Override
				public void keyReleased(java.awt.event.KeyEvent e) {
					validateInput();
				}
			});
		}
		return RoomWidth;
	}

	public String getRoomWidthString() {
		return RoomWidth.getText();
	}

	/**
	 * This method initializes Type
	 * 
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getType() {
		if (Type == null) {
			Type = new JComboBox(houseHold.RoomType.toList());
			Type.setBounds(new Rectangle(80, 20, 140, 25));
			Type.setBackground(new Color(250, 250, 250));
			Type.setFont(new Font("SansSerif", Font.BOLD, 12));
			Type.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					RoomName.setText((String) Type.getSelectedItem() + "#"
							+ IDGenerator.getNextRoomID());
					rName = (String) Type.getSelectedItem();
				}
			});
		}
		return Type;
	}

	public int getTypeIndex() {
		return Type.getSelectedIndex();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */

	private void initialize() {
		this.setSize(440, 460);
		AddRoomDialogMain = getAddRoomDialogMain();
		AddRoomDialogMain.setSize(new Dimension(328, 298));
		this.setContentPane(getMainPanel());
		this.setTitle("House Editor");
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent e) {
				MainGUI.getInstance().setEnabled(true);
				HouseEditor.this.setVisible(false);
			}
		});
		clearRoomDialog();
	}

	public void setRoomErrorText(String s, Color c) {
		RoomError.setText(s);
		RoomError.setForeground(c);
	}

	private boolean validate(String s) {
		try {
			Integer.parseInt(s);
		} catch (Exception e1) {
			writeError("Invalid number format", Constants.red);
			return false;
		}
		return true;
	}

	private void validateInput() {
		String w, h, l, n;
		boolean[] values = new boolean[4];
		w = RoomWidth.getText();
		h = RoomHeight.getText();
		l = RoomLength.getText();
		n = RoomName.getText();
		if (w.length() > 0) {
			values[0] = validate(w);
		}
		if (h.length() > 0) {
			values[1] = validate(h);
		}
		if (l.length() > 0) {
			values[2] = validate(l);
		}
		if (n.length() > 0) {
			values[3] = true;
		}
		if (values[1] && values[2] && values[3] && values[0]) {
			Add.setEnabled(true);
			writeError("Data OK", Constants.green);
		} else
			Add.setEnabled(false);

	}

	/**
	 * This method initializes RoomPopUp
	 * 
	 * @return javax.swing.JPopupMenu
	 */

	void writeError(String string, Color c) {
		RoomError.setText(string);
		RoomError.setForeground(c);
	}

} // @jve:decl-index=0:visual-constraint="49,26"
